独学プログラマー コード改善: 20章 Google Newsのクローラー
20章, Google Newsのクローラー
修正版コードを用意しました。出版社サイトからダウンロードできます
以下は上記ダウンロードと同じ内容です
以下のように書き換えることで、日経Trendyニュースを取得出来るようになる
2020/05/27更新 サイトが日経Trendyから日経クロストレンドに移行したようで、サイト構造が変わってました。古いコードを持っている方は、以下のようにコード修正してください。
2. URLパス条件を変更: if 'atcl/news' -> if 'atcl/contents'
3. (おまけ)リダイレクト対策として: urljoin(self.site, url) を urljoin(r.url, url) に変更
code:chap20-crawler-nikkeibp-trendy-news.py
import urllib.request
from urllib.parse import urljoin # URLを扱うモジュールを追加
from bs4 import BeautifulSoup as BS
class Scraper:
def __init__(self, site):
self.site = site
def scrape(self):
r = urllib.request.urlopen(self.site)
html = r.read()
parser = 'html.parser'
sp = BS(html, parser)
for tag in sp.find_all('a'):
url = tag.get('href')
if url is None:
continue
if 'atcl/contents' in url: # 'atcl/contents' を含むURLだけを取り出す条件に変更
print('\n' + urljoin(r.url, url)) # ドメイン名を含むURLに変換して表示
Scraper(news).scrape()
ただ、これだと同じURLを拾ってしまうので、以下のようにURL重複を避けるコードにすると良い。
code:chap20-crawler-nikkeibp-trendy-news-nodup.py
import urllib.request
from urllib.parse import urljoin # URLを扱うモジュールを追加
from bs4 import BeautifulSoup as BS
class Scraper:
def __init__(self, site):
self.site = site
self.urls = set() # 収集済みURLを入れておく変数
def scrape(self):
r = urllib.request.urlopen(self.site)
html = r.read()
parser = 'html.parser'
sp = BS(html, parser)
for tag in sp.find_all('a'):
url = tag.get('href')
if url is None:
continue
if 'atcl/contents' not in url: # 'atcl/contents' を含まないURLは対象外にする
continue
full_url = urljoin(r.url, url) # ドメイン名を含むURLに変換
if full_url in self.urls: # 既に収集済みのURLは対象外にする
continue
self.urls.add(full_url) # 収集済みURLに追加
print('\n' + full_url) # URLを表示
Scraper(news).scrape()